home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / monitory / sfragmem / sfragmem.c < prev    next >
C/C++ Source or Header  |  1992-11-21  |  13KB  |  521 lines

  1. /* SFragMem (ShowFragmentationOfMemory)
  2.  *
  3.  * (c) 1992 Thies Wellpott
  4.  *
  5.  * compile (SAS C 5.10): LC -cfistu -rr -v -Hprecompiled
  6.  * link: BLink FROM LIB:c.o,SFragMem.o TO SFragMem LIB LIB:amiga.lib,LIB:lcr.lib
  7.  *        SC SD ND DEFINE @_main=@_tinymain
  8.  *
  9.  *
  10.  * History
  11.  *
  12.  * V0.9  6.10.02
  13.  *   first code, working version without "Next" and "Info"
  14.  *
  15.  * V1.0  8.10.92
  16.  *   "Next" and "Info" menuitems finished, Icon-ToolTypes configuration added,
  17.  *
  18.  * V1.01  8.10.92
  19.  *   Menus are now really disabled when info-wd is open; better scala at the
  20.  *   left side, adjusts itself to the window size
  21.  */
  22.  
  23. #include <clib/alib_stdio_protos.h>
  24.  
  25. #define VERSION "1.01"
  26. #define DATE "8.10.92"
  27.  
  28. #define NORMAL_POINTER ClearPointer(window)
  29. #define BUSY_POINTER SetPointer(window, busy_ptr_data, 16, 16, -6, 0)
  30.  
  31. #define FREECOLOR 2
  32. #define USEDCOLOR 3
  33.  
  34.  
  35. struct config
  36. {
  37.    UWORD wd_x,wd_y, wd_w,wd_h;
  38. };
  39.  
  40. /*** global variables ***/
  41. char version[] = "\0$VER: SFragMem V"VERSION" ("DATE")";
  42. struct WBStartup *wbmsg = NULL;
  43.  
  44. extern struct ExecBase *SysBase;
  45. struct Library *GadToolsBase = NULL, *IconBase = NULL;
  46. struct GfxBase *GfxBase = NULL;
  47. struct IntuitionBase *IntuitionBase = NULL;
  48.  
  49. struct Window *window = NULL;
  50. UWORD wd_x0, wd_y0;
  51. struct RastPort *rp;
  52.  
  53. struct config config =
  54. {
  55.    0,0, 500,180
  56. };
  57.  
  58. UWORD mem_x,mem_y, mem_w,mem_h;
  59. struct MemHeader *memhdr;
  60. APTR mem_start, mem_end;
  61. ULONG mem_len;
  62. UWORD bpp;
  63.  
  64. APTR vinfo;
  65. struct Menu *menu;
  66. struct NewMenu menu_data[] =
  67. {
  68.    {NM_TITLE, "Project",   NULL, 0, 0, NULL},
  69.    { NM_ITEM, "About...",  "A",  0, 0, NULL},
  70.    { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL},
  71.    { NM_ITEM, "Quit",      "Q",  0, 0, NULL},
  72.    {NM_TITLE, "Memory",   NULL, 0, 0, NULL},
  73.    { NM_ITEM, "Next",      "N",  0, 0, NULL},
  74.    { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL},
  75.    { NM_ITEM, "Refresh",   "R",  0, 0, NULL},
  76.    { NM_ITEM, NM_BARLABEL, NULL, 0, 0, NULL},
  77.    { NM_ITEM, "Info",      "I",  0, 0, NULL},
  78.    {  NM_END, NULL, NULL, 0, 0, NULL}
  79. };
  80.  
  81. #define MENU_ABOUT   FULLMENUNUM(0,0,NOSUB)
  82. #define MENU_QUIT    FULLMENUNUM(0,2,NOSUB)
  83. #define MENU_NEXT    FULLMENUNUM(1,0,NOSUB)
  84. #define MENU_REFRESH FULLMENUNUM(1,2,NOSUB)
  85. #define MENU_INFO    FULLMENUNUM(1,4,NOSUB)
  86.  
  87. struct EasyStruct AboutES =
  88.    {sizeof(struct EasyStruct), 0, "About...",
  89.    "SFragMem V"VERSION" ("DATE")\n© 1992 Thies Wellpott\n\
  90. This programm is freely distributable", "Ok"};
  91.  
  92.  
  93. UWORD chip busy_ptr_data[] =
  94. {
  95.    0x0000,0x0000,          /* OS 2.0 busy pointer */
  96.    0x0400,0x07C0, 0x0000,0x07C0, 0x0100,0x0380, 0x0000,0x07E0,
  97.    0x07C0,0x1FF8, 0x1FF0,0x3FEC, 0x3FF8,0x7FDE, 0x3FF8,0x7FBE,
  98.    0x7FFC,0xFF7F, 0x7EFC,0xFFFF, 0x7FFC,0xFFFF, 0x3FF8,0x7FFE,
  99.    0x3FF8,0x7FFE, 0x1FF0,0x3FFC, 0x07C0,0x1FF8, 0x0000,0x07E0,
  100.    0x0000,0x0000,
  101. };
  102.  
  103.  
  104. /*** functions ***/
  105.  
  106. void close_all(char *s, int err)
  107. {
  108.    if (window)
  109.    {
  110.       ClearMenuStrip(window);
  111.       CloseWindow(window);
  112.       FreeMenus(menu);           /* only alloc., if window opened!! */
  113.       FreeVisualInfo(vinfo);
  114.    }
  115.  
  116.    if (GadToolsBase)    CloseLibrary(GadToolsBase);
  117.    if (IntuitionBase)   CloseLibrary((struct Library *)IntuitionBase);
  118.    if (GfxBase)         CloseLibrary((struct Library *)GfxBase);
  119.  
  120.    if (s)                              /* wenn ein String angegeben ist, */
  121.    {
  122.       LONG out;
  123.  
  124.       /* da stdout nicht definiert ist, wird hier ein Window geöffnet,
  125.        * auf dem der String ausgegeben wird */
  126.       if (wbmsg)
  127.      out = Open("CON:20/20/260/100/SFragMem error/CLOSE/WAIT", MODE_NEWFILE);
  128.       else
  129.      out = Open("*", MODE_NEWFILE);
  130.  
  131.       if (out)
  132.       {
  133.      fputs(s, out);                /* diesen ausgeben */
  134.      fputs("!\n", out);            /* "!" + LF anhängen */
  135.      Close(out);
  136.       } /* if (out) */
  137.    } /* if (s) */
  138.  
  139.    exit(err);
  140. }
  141.  
  142.  
  143. void open_all(void)
  144. {
  145.    if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 33)))
  146.       close_all("No graphics.library", 20);
  147.    if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37)))
  148.       close_all("No intuition.library", 20);
  149.    if (!(GadToolsBase = OpenLibrary("gadtools.library", 37)))
  150.       close_all("No gadtools.library", 20);
  151. }
  152.  
  153.  
  154. void open_window(void)
  155. {
  156.    struct Screen *scr;
  157.  
  158.    if (wbmsg)
  159.    {
  160.       if (IconBase = OpenLibrary("icon.library", 33))
  161.       {
  162.      BPTR olddir;
  163.      struct DiskObject *diskobj;
  164.      char *s;
  165.  
  166.      olddir = CurrentDir(wbmsg->sm_ArgList->wa_Lock);
  167.      if (diskobj = GetDiskObject(wbmsg->sm_ArgList->wa_Name))
  168.      {
  169.         if (s = FindToolType(diskobj->do_ToolTypes, "WINDOWX"))
  170.            config.wd_x = atoi(s);
  171.         if (s = FindToolType(diskobj->do_ToolTypes, "WINDOWY"))
  172.            config.wd_y = atoi(s);
  173.         if (s = FindToolType(diskobj->do_ToolTypes, "WINDOWWIDTH"))
  174.            config.wd_w = atoi(s);
  175.         if (s = FindToolType(diskobj->do_ToolTypes, "WINDOWHEIGHT"))
  176.            config.wd_h = atoi(s);
  177.  
  178.         FreeDiskObject(diskobj);
  179.      } /* if (GetDiskObject()) */
  180.  
  181.      CurrentDir(olddir);
  182.      CloseLibrary(IconBase);
  183.       } /* if (OpenLibrary()) */
  184.    } /* if (wbmsg) */
  185.  
  186.    if (!(scr = LockPubScreen(NULL)))
  187.       goto e1;
  188.    if (!(vinfo = GetVisualInfo(scr, TAG_DONE)))
  189.       goto e2;
  190.  
  191.    /*** Menu init. ***/
  192.    if (!(menu = CreateMenus(menu_data, GTMN_FullMenu,TRUE, TAG_DONE)))
  193.       goto e3;
  194.    if (!LayoutMenus(menu, vinfo, TAG_DONE))
  195.       goto e4;
  196.  
  197.    if (!(window = OpenWindowTags(NULL,
  198.         WA_Left,config.wd_x,  WA_Top,config.wd_y,
  199.         WA_InnerWidth,config.wd_w,    WA_InnerHeight,config.wd_h,
  200.         WA_Flags,WFLG_DRAGBAR | WFLG_SIZEGADGET | WFLG_DEPTHGADGET |
  201.            WFLG_CLOSEGADGET | WFLG_SMART_REFRESH | WFLG_ACTIVATE,
  202.         WA_MinWidth,190,  WA_MinHeight,50,    WA_MaxWidth,~0,  WA_MaxHeight,~0,
  203.         WA_Title, "SFragMem V"VERSION,  WA_AutoAdjust,TRUE)))
  204.       goto e4;
  205.    UnlockPubScreen(NULL, scr);
  206.    SetMenuStrip(window, menu);
  207.    wd_x0 = window->BorderLeft;
  208.    wd_y0 = window->BorderTop;     /* scr->WBorTop + scr->Font->ta_YSize + 1 */
  209.    rp = window->RPort;
  210.  
  211.       /* space wdborder<>num, two chars, space num<>line, line, space line<>mem */
  212.    mem_x = wd_x0 + 6 + 2*8 + 2 + 4 + 2;
  213.    mem_y = wd_y0 + 4;
  214.    mem_h = window->Height - mem_y - 5 - window->BorderBottom;
  215.  
  216.    return;
  217.  
  218.  
  219. e4:   FreeMenus(menu);           /* bei Fehler, alle Dinge freigeben */
  220. e3:   FreeVisualInfo(vinfo);
  221. e2:   UnlockPubScreen(NULL, scr);
  222. e1:   close_all("Can`t open window", 20);
  223. }
  224.  
  225.  
  226.  
  227. UWORD calc_x(ULONG adr)
  228. {
  229.    return (mem_x + (adr - (ULONG)mem_start) / bpp % mem_w);
  230. }
  231.  
  232. UWORD calc_y(ULONG adr)
  233. {
  234.    return (mem_y + (adr - (ULONG)mem_start) / bpp / mem_w);
  235. }
  236.  
  237. void draw_free(ULONG adr, ULONG len)
  238. {
  239.    UWORD x1,y1,x2,y2;
  240.  
  241.    if (len > bpp / 2)
  242.    {
  243.       x1 = calc_x(adr);
  244.       y1 = calc_y(adr);
  245.       x2 = calc_x(adr + len-1);
  246.       y2 = calc_y(adr + len-1);
  247.  
  248.       if (y1 == y2)
  249.       {
  250.      Move(rp, x1,y1);
  251.      Draw(rp, x2,y1);
  252.       }
  253.       else
  254.       {
  255.      Move(rp, x1,y1);
  256.      Draw(rp, mem_x+mem_w-1,y1);
  257.      if (y2 > y1+1)
  258.         RectFill(rp, mem_x,y1+1, mem_x+mem_w-1,y2-1);
  259.      Move(rp, mem_x,y2);
  260.      Draw(rp, x2,y2);
  261.       }
  262.    } /* if (len) */
  263. }
  264.  
  265.  
  266. void draw_memlist(void)
  267. {
  268.    struct MemChunk *chunk;
  269.  
  270.    SetAPen(rp, FREECOLOR);
  271.  
  272.    Forbid();
  273.    chunk = memhdr->mh_First;
  274.    do
  275.    {
  276.       draw_free((ULONG)chunk, chunk->mc_Bytes);
  277.    } while (chunk = chunk->mc_Next);
  278.    Permit();
  279. }
  280.  
  281.  
  282. void refresh_wd(void)
  283. {
  284.    UWORD i,a,y;
  285.    char str[6];
  286.  
  287.    BUSY_POINTER;
  288.    ModifyIDCMP(window, 0);
  289.  
  290.    mem_w = window->Width - mem_x - 6 - window->BorderRight;
  291.  
  292.    mem_h = window->Height - mem_y - 5 - window->BorderBottom;
  293.    bpp = MAX((mem_len / (8 * mem_w * mem_h) + 1) * 8, 8);
  294.    mem_h = mem_len / (mem_w * bpp);
  295.  
  296.    {
  297.       struct Message *msg;
  298.       ModifyIDCMP(window, IDCMP_NEWSIZE);
  299.       SizeWindow(window, 0, mem_y + mem_h + 5 + window->BorderBottom - window->Height + 1);
  300.       WaitPort(window->UserPort);
  301.       while (msg = GetMsg(window->UserPort))
  302.      ReplyMsg(msg);
  303.       ModifyIDCMP(window, 0);
  304.    }
  305.  
  306.    SetAPen(rp, 0);
  307.    RectFill(rp, wd_x0,mem_y-1, window->Width - window->BorderRight - 1,
  308.      window->Height - window->BorderBottom - 1);
  309.  
  310.    SetAPen(rp, USEDCOLOR);
  311.    RectFill(rp, mem_x,mem_y, mem_x+mem_w-1,mem_y+mem_h-1);
  312.  
  313.    SetAPen(rp, 1);
  314.    Move(rp, mem_x-1,mem_y-1);
  315.    Draw(rp, mem_x+mem_w, mem_y-1);
  316.    Draw(rp, mem_x+mem_w, mem_y+mem_h);
  317.    Draw(rp, mem_x-1, mem_y+mem_h);
  318.    Draw(rp, mem_x-1, mem_y-1);
  319.  
  320.    Move(rp, calc_x((ULONG)mem_end), mem_y+mem_h-1);
  321.    Draw(rp, mem_x+mem_w, mem_y+mem_h-1);
  322.  
  323.    a = 1;
  324.    while (calc_y((ULONG)mem_start + a*512*1024) - calc_y((ULONG)mem_start) < 5)
  325.       a *= 2;
  326.  
  327.    for (i = 0; i <= (mem_len+0x420)/(512*1024); i += a)
  328.    {
  329.       y = calc_y((ULONG)mem_start + i * 512*1024);
  330.       if ((i/a & 1) == 0)
  331.       {
  332.      Move(rp, wd_x0 + 6, y+3);
  333.      sprintf(str, "%2ld", i/2);
  334.      Text(rp, str, 2);
  335.       }
  336.       Move(rp, wd_x0 + 6+2*8+1, y);
  337.       Draw(rp, wd_x0 + 6+2*8+4, y);
  338.    }
  339.  
  340.    draw_memlist();
  341.  
  342.    ModifyIDCMP(window, IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | IDCMP_NEWSIZE);
  343.    NORMAL_POINTER;
  344. }
  345.  
  346.  
  347. void next_memhdr(void)
  348. {
  349.    memhdr = memhdr->mh_Node.ln_Succ;
  350.    if (memhdr->mh_Node.ln_Succ == NULL)
  351.       memhdr = SysBase->MemList.lh_Head;
  352.    mem_start = memhdr->mh_Lower;
  353.    mem_end = memhdr->mh_Upper;
  354.    mem_len = (ULONG)mem_end - (ULONG)mem_start;
  355.    refresh_wd();
  356. }
  357.  
  358.  
  359. void info_window(void)
  360. {
  361.    struct Window *iwd;
  362.    struct RastPort *irp;
  363.    UWORD x0,y0;
  364.    struct IntuiMessage *msg;
  365.    BOOL iende = FALSE;
  366.    char str[40];
  367.  
  368.    BUSY_POINTER;
  369.    ModifyIDCMP(window, IDCMP_NEWSIZE);
  370.    OffMenu(window, FULLMENUNUM(0,NOITEM,NOSUB));
  371.    OffMenu(window, FULLMENUNUM(1,NOITEM,NOSUB));
  372.  
  373.    if (iwd = OpenWindowTags(NULL,
  374.      WA_Left,window->LeftEdge+wd_x0+2,  WA_Top,window->TopEdge+wd_y0,
  375.      WA_InnerWidth,252,  WA_InnerHeight,112,  WA_AutoAdjust,TRUE,
  376.      WA_Flags,WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET |
  377.         WFLG_SMART_REFRESH | WFLG_RMBTRAP | WFLG_ACTIVATE,
  378.      WA_IDCMP, IDCMP_CLOSEWINDOW,
  379.      WA_Title,"SFM Information"))
  380.    {
  381.       irp = iwd->RPort;
  382.       x0 = iwd->BorderLeft+6;
  383.       y0 = iwd->BorderTop+4;
  384.  
  385.       SetAPen(irp, FREECOLOR);
  386.       RectFill(irp, x0,y0, x0+9*8+6,y0+10);
  387.       SetAPen(irp, USEDCOLOR);
  388.       RectFill(irp, x0+90,y0, x0+90+9*8+6,y0+10);
  389.       SetAPen(irp, 1);
  390.       SetDrMd(irp, JAM1);
  391.       Move(irp, x0+3,y0+2+6);
  392.       Text(irp, "Free area", 9);
  393.       Move(irp, x0+90+3,y0+2+6);
  394.       Text(irp, "Used area", 9);
  395.  
  396.       sprintf(str, "%ld bytes per pixel", bpp);
  397.       Move(irp, x0,y0+14+6);
  398.       Text(irp, str, strlen(str));
  399.  
  400.       sprintf(str, "block length: %ld (%ld MB)", mem_len, (mem_len+0x420)/(1024*1024));
  401.       Move(irp, x0,    y0+14+ 16+0*9+6);
  402.       Text(irp, str, strlen(str));
  403.       sprintf(str, "used: %ld", mem_len - memhdr->mh_Free);
  404.       Move(irp, x0+8*8,y0+14+ 16+1*9+6);
  405.       Text(irp, str, strlen(str));
  406.       sprintf(str, "free: %ld", memhdr->mh_Free);
  407.       Move(irp, x0+8*8,y0+14+ 16+2*9+6);
  408.       Text(irp, str, strlen(str));
  409.  
  410.       sprintf(str, "Lower: $%08lx", memhdr->mh_Lower);
  411.       Move(irp, x0,y0+48+ 14+0*9+6);
  412.       Text(irp, str, strlen(str));
  413.       sprintf(str, "Upper: $%08lx", memhdr->mh_Upper);
  414.       Move(irp, x0,y0+48+ 14+1*9+6);
  415.       Text(irp, str, strlen(str));
  416.       sprintf(str, "Attributes: $%04lx", memhdr->mh_Attributes);
  417.       Move(irp, x0,y0+48+ 14+2*9+6);
  418.       Text(irp, str, strlen(str));
  419.  
  420.       Move(irp, x0,y0+80+ 18+6);
  421.       Text(irp, "Close window to continue", 24);
  422.  
  423.       while (!iende)
  424.       {
  425.      WaitPort(iwd->UserPort);
  426.      while (msg = (struct IntuiMessage *)GetMsg(iwd->UserPort))
  427.      {
  428.         if (msg->Class == IDCMP_CLOSEWINDOW)
  429.            iende = TRUE;
  430.         ReplyMsg((struct Message *)msg);
  431.      } /* while (GetMsg()) */
  432.       } /* while (!iende) */
  433.  
  434.       CloseWindow(iwd);
  435.    } /* if (OpenWindowTags()) */
  436.    else
  437.       DisplayBeep(NULL);
  438.  
  439.    OnMenu(window, FULLMENUNUM(0,NOITEM,NOSUB));
  440.    OnMenu(window, FULLMENUNUM(1,NOITEM,NOSUB));
  441.    ModifyIDCMP(window, IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | IDCMP_NEWSIZE);
  442.    NORMAL_POINTER;
  443. }
  444.  
  445.  
  446. void mainloop(void)
  447. {
  448.    BOOL ende = FALSE;
  449.    struct IntuiMessage *msg;
  450.    ULONG class;
  451.    UWORD code;
  452.  
  453.    ModifyIDCMP(window, IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | IDCMP_NEWSIZE);
  454.  
  455.    while (!ende)
  456.    {
  457.       WaitPort(window->UserPort);
  458.       while (!ende && (msg = GT_GetIMsg(window->UserPort)))
  459.       {
  460.      class = msg->Class;
  461.      code = msg->Code;
  462.      GT_ReplyIMsg(msg);
  463.  
  464.      switch (class)
  465.      {
  466.         case IDCMP_MENUPICK:
  467.            while (!ende && (code != MENUNULL))
  468.            {
  469.           switch (code)
  470.           {
  471.              case MENU_ABOUT:
  472.             EasyRequest(window, &AboutES, NULL, NULL);
  473.             break;
  474.              case MENU_QUIT:
  475.             ende = TRUE;
  476.             break;
  477.              case MENU_NEXT:
  478.             next_memhdr();
  479.             break;
  480.              case MENU_REFRESH:
  481.             refresh_wd();
  482.             break;
  483.              case MENU_INFO:
  484.             info_window();
  485.             break;
  486.           } /* switch (code) */
  487.           code = ItemAddress(menu, code)->NextSelect;
  488.            } /* while (code != MENUNULL) */
  489.            break;
  490.         case IDCMP_NEWSIZE:
  491.            refresh_wd();
  492.            break;
  493.         case IDCMP_CLOSEWINDOW:
  494.            ende = TRUE;
  495.            break;
  496.      } /* switch (class) */
  497.       } /* while (GT_GetIMsg()) */
  498.    } /* while (!ende) */
  499. }
  500.  
  501.  
  502. void main(int argc, char *argv[])
  503. {
  504.    if (argc == 0)
  505.       wbmsg = (struct WBStartup *)argv;
  506.  
  507.    open_all();
  508.    open_window();
  509.  
  510.    memhdr = SysBase->MemList.lh_Head;
  511.    mem_start = memhdr->mh_Lower;
  512.    mem_end = memhdr->mh_Upper;
  513.    mem_len = (ULONG)mem_end - (ULONG)mem_start;
  514.    refresh_wd();
  515.  
  516.    mainloop();
  517.  
  518.    close_all(NULL, 0);
  519. }
  520.  
  521.